using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Xml;
using System.Web;
using System.Windows.Forms;
using System.IO;

namespace ForumExplorer.Extension.Tagging
{
    /// <summary>
    /// The thread class contains both a ThreadID and the subject of the thread.  This would
    /// be the correct object to augment if we wanted to hold more metadata about threads
    /// in the future
    /// </summary>
    public class Thread
    {
        public int threadID;
        public string subject;
        public bool answered;

        public Thread(int _threadID, string _subject, bool _answered)
        {
            threadID = _threadID;
            subject = _subject;
            answered = _answered;
        }
    }

    public class Tagging
	{
		#region SetCredentialsCompleted event
		public event EventHandler<EventArgs> SetCredentialsCompleted;
		protected void OnSetCredentialsCompleted ( EventArgs e )
		{
			if (this.SetCredentialsCompleted != null)
			{
				SetCredentialsCompleted(this, e);
			}
		}
		#endregion SetCredentialsCompleted event

		private string token = String.Empty;
        public bool isLoggedIn;
        public ForumExplorer.Extension.Delicious.msmoderators.com.Service taggingService = new ForumExplorer.Extension.Delicious.msmoderators.com.Service();

        public Tagging()
        {
            isLoggedIn = false;
        }

        //This method will return true if the credentials passed to it are valid, false if not

        public bool SetCredentials(string username, string password)
        {
            try
            {
				taggingService.LoginCompleted += new ForumExplorer.Extension.Delicious.msmoderators.com.LoginCompletedEventHandler(taggingService_LoginCompleted);
                taggingService.LoginAsync(username, password);
            }
            catch 
            {
                return false;
            }
            if (token != String.Empty)
            {
                MessageBox.Show("You have been logged on as " + username + " to msmoderators.com.");
                isLoggedIn = true;
                return true;
            }
            else
                return false;
        }

		void taggingService_LoginCompleted ( object sender, ForumExplorer.Extension.Delicious.msmoderators.com.LoginCompletedEventArgs e )
		{
			try
			{
				this.isLoggedIn = false;
				String token = e.Result as String;
				if (!String.IsNullOrEmpty(token))
				{
					this.isLoggedIn = true;
					this.token = token;
				}
			}
			catch
			{
			}
			OnSetCredentialsCompleted(EventArgs.Empty);
		}

        public void Logout()
        {
            isLoggedIn = false;
            token = null;
        }

        //This method has the general logic to setup a connection to the del.icio.us API
        //private void SetupConnection(string type, string uriName)
        //{
        //    //create placeholder URI and create a new webrequest for it
        //    Uri uri = new Uri(uriName);
        //    request = HttpWebRequest.Create(uri);

        //    //setup network credentials
        //    credentials = new System.Net.NetworkCredential(username, password);
        //    request.Credentials = credentials;

        //    //set the HTTP method being used
        //    request.Method = type;
        //}

        //create a webresponse to read the response from the del.icio.us API, and do the
        //voodoo to change it into an XML document
        /// <revisionHistory>
        /// <revision author="Moayad Mardini [mardini]" date="26-August-2006">
        /// Add Try-Catch block
        /// </revision>
        /// </revisionHistory>
        /// Joemorel - I removed the try/catch block from this part in the code because we might want to see those errors further up the stack
        /// This method can throw a WebException (401: Authorized) if the user inputs invalid credentials
        //private XmlDocument WebResponseToXML()
        //{
        //    System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
        //    //try
        //    //{
        //        System.Net.WebResponse response = request.GetResponse();
        //        System.IO.Stream stream = response.GetResponseStream();
        //        System.IO.StreamReader reader = new System.IO.StreamReader(stream);
        //        doc.LoadXml(reader.ReadToEnd());
        //        stream.Close();
        //        reader.Close();
        //    //}
        //    //catch
        //    //{
        //    //  System.Windows.Forms.MessageBox.Show(@"Error, you may wrote a wrong username or a password",@"Error",System.Windows.Forms.MessageBoxButtons.OK,System.Windows.Forms.MessageBoxIcon.Error);
        //    //}
        //    return doc;
        //}

        //public XmlDocument GetUserTags()
        //{
        //    SetupConnection("GET","https://api.del.icio.us/v1/tags/get");
        //    XmlDocument doc = WebResponseToXML();
        //    return doc;
        //}
        //public XmlDocument SearchRecentThreads(string tag)
        //{
        //    string URL = "https://api.del.icio.us/v1/posts/recent?tag=" + tag;
        //    XmlDocument doc = WebResponseToXML();
        //    return doc;
        //}

        public void TagThread(string tag, string subject, string ID)
        {
            try
            {
                int temp = Convert.ToInt32(ID);
                if (isLoggedIn && (temp != 0))
                    taggingService.TagThread(temp, tag, subject, token);
                else
                {
                    MessageBox.Show("Please Login to MSModerators.com to use tagging features.");
                }
            }
            catch (System.FormatException e)
            {
                MessageBox.Show(e.Message);
            }
            catch (System.Web.Services.Protocols.SoapException e)
            {
                MessageBox.Show(e.Message);
            }
            catch (System.ArgumentException e)
            {
                MessageBox.Show(e.Message);
            }
        }

        /// <summary>
        /// Returns a list of tags for a given thread
        /// </summary>
        /// <param name="threadID">threadID of the thread that we want to find the tags for</param>
        /// <returns>an array of strings that are the tags</returns>
        public string[] GetTagsForThreadID(int threadID)
        {
            if (isLoggedIn)
            {
                try
                {
                    return taggingService.GetTagsForThread(threadID, token);
                }
                catch (System.Web.Services.Protocols.SoapException)
                {
                    MessageBox.Show("The web services appear to be busy.  Please wait a few seconds and try again.");
                    return null;
                }
            }
            else
            {
                MessageBox.Show("Please Login to MSModerators.com to use tagging features.");
                return null;
            }
		}

		#region
		public class GetThreadIDsEventArgs : EventArgs
		{
			int[] ids;
			public GetThreadIDsEventArgs ( int[] IDs )
			{
				this.ids = IDs;
			}
			public int[] IDs
			{
				get
				{
					return ids != null ? ids.Clone() as int[]: null;
				}
			}
		}
		public event EventHandler<GetThreadIDsEventArgs> GetThreadIDsForTagCompleted;
		protected void OnGetThreadIDsForTagCompleted ( GetThreadIDsEventArgs e )
		{
			if (this.GetThreadIDsForTagCompleted != null)
			{
				this.GetThreadIDsForTagCompleted(this, e);
			}
		}
		#endregion

		public void GetThreadIDsforTag(string tag)
        {
			if (isLoggedIn)
			{
				if (this.GetThreadIDsForTagCompleted == null)
				{
					throw new InvalidOperationException("No event handler to handle GetThreadIDsForTagCompleted event.");
				}
				taggingService.GetThreadsbyTagCompleted += new ForumExplorer.Extension.Delicious.msmoderators.com.GetThreadsbyTagCompletedEventHandler(taggingService_GetThreadsbyTagCompleted);
				taggingService.GetThreadsbyTagAsync(tag, token);
			}
			else
			{
				MessageBox.Show("Please Login to MSModerators.com to use tagging features.");
			}
        }

		void taggingService_GetThreadsbyTagCompleted ( object sender, ForumExplorer.Extension.Delicious.msmoderators.com.GetThreadsbyTagCompletedEventArgs e )
		{
			taggingService.GetThreadsbyTagCompleted -= new ForumExplorer.Extension.Delicious.msmoderators.com.GetThreadsbyTagCompletedEventHandler(taggingService_GetThreadsbyTagCompleted);
			OnGetThreadIDsForTagCompleted(new GetThreadIDsEventArgs(e.Result as int[]));
		}

		#region
		public class GetThreadsForTagEventArgs : EventArgs
		{
			Thread[] threads;
			String searchText;
			Object state;
			public GetThreadsForTagEventArgs ( Object state, String searchText, Thread[] threads )
			{
				this.searchText = searchText;
				this.threads = threads;
				this.state = state;
			}
			public Object State
			{
				get
				{
					return this.state;
				}
			}
			public String SearchText
			{
				get
				{
					return this.searchText;
				}
			}
			public Thread[] Threads
			{
				get
				{
					return threads != null ? threads.Clone() as Thread[]: null;
				}
			}
		}
		public event EventHandler<GetThreadsForTagEventArgs> GetThreadsForTagCompleted;
		protected void OnGetThreadsForTagCompleted(GetThreadsForTagEventArgs e)
		{
			if (GetThreadsForTagCompleted != null)
			{
				GetThreadsForTagCompleted(this, e);
			}
		}
		#endregion

		private void GetThreadsForTagCore ( Object o, string tag )
		{
			Thread[] threads = null;

			try
			{
				int[] threadIDs = taggingService.GetThreadsbyTag(tag, token);
				string subject;
				List<Thread> threadList = new List<Thread>();
				Thread temp;
                HttpWebRequest request;
                WebResponse response;
                bool answered;
                string doc;
                StreamReader responseStreamreader;
				for (int i = 0; i < threadIDs.Length; i++)
				{
					subject = taggingService.GetSubjectforThreadID(threadIDs[i], token);
                    request = (HttpWebRequest) WebRequest.Create("http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=" + threadIDs[i].ToString() + "&SiteID=1");
                    response = request.GetResponse();
                    responseStreamreader = new StreamReader(response.GetResponseStream());
                    doc = responseStreamreader.ReadToEnd();
                    if (doc.Contains("IsAnswered\" content=\"0\""))
                        answered = false;
                    else
                        answered = true;
					temp = new Thread(threadIDs[i], subject, answered);
					threadList.Add(temp);
				}
				threads = threadList.ToArray();
			}
			finally
			{
				OnGetThreadsForTagCompleted(new GetThreadsForTagEventArgs(o, tag, threads));
			}
		}

        public void GetThreadsforTag(Object o, string tag)
        {
            if (isLoggedIn)
            {
				if (GetThreadsForTagCompleted == null)
				{
					throw new InvalidOperationException("No handler for GetThreadsForTagCompleted event.");
				}

				((MethodInvoker)delegate
				{
					GetThreadsForTagCore(o, tag);
				}).BeginInvoke(null, null);
            }
            else
            {
                MessageBox.Show("Please Login to MSModerators.com to use tagging features.");
            }
        }

        public int CreateNewAccount(string username, string password, string secret)
        {
            return taggingService.CreateNewUser(username, password, secret);
        }

        public string[] GetTopTags()
        {
            if (isLoggedIn)
                return taggingService.GetTopTags(token);
            else
            {
                MessageBox.Show("Please Login to MSModerators.com to use tagging features.");
                return null;
            }
        }
    }
}
